#pragma once
#include "EDAABB.h"
#include "matrix4.h"
#include "Action.h"
#include <queue>
class Object;



class SGKAgent;

class CBrain
{
private:
	// neuralNetwork m_nn; // BRUHAHAHAHAHHAHHAHAHAHAHHAHAHHAHHAHA
	std::queue<Action *> m_plan;
	std::vector<Action *> availableActions; // once system is dynamic, these will be pointers to objects in a Master List.

	Action * m_pCurrentAction;

	SGKAgent * m_pOwner;


public:
	CBrain();

	~CBrain();
	bool formulatePlan(Condition * goal, value val);
	void getOwned(SGKAgent * owner);
	float disparity(Action * from, Action * to);

	Action * GetCurrentAction(void){return m_pCurrentAction;}

	void update(float dt);
	void init(SGKAgent * owner);

	char * currentBehavior(void)
	{
		if (m_plan.size())
		{
			m_pCurrentAction = m_plan.front();
			return m_plan.front()->GetName();
		}
		else
		{
			return "[none]";
		}
	}
};

class SGKAgent
{
private:

	vec3f m_Center;
	float m_fRadius;
	GLUquadric * quad;
	matrix4f m_Matrix;
	vec3f m_Dest;
	CBrain m_Brain;
	Object * m_pObject;
	Object * m_pTarget; // since we dont have a player yet..


public:

	SGKAgent(void);

	//~SGKAgent(void);

	void Draw(void);

	// Takes in a string and a RELATIVE position.
	void DrawText(char * text, vec3f pos);

	void Init(void);

	void Kill(void);

	void Update(float dt);

public:

	//Accessors and Mutators
	const vec3f& GetCenter(void){ return m_Center; }

	const float GetRadius(void){ return m_fRadius; }

	inline void SetCenter(const vec3f& center) { m_Matrix.wx = center.x; m_Matrix.wy = center.y; m_Matrix.wz = center.z; }

	inline void SetCenter(const float fX, const float fY, const float fZ) { m_Matrix.wx = fX; m_Matrix.wy = fY; m_Matrix.wz = fZ; }

	inline void SetDestination(vec3f dest) {m_Dest.x = dest.x; m_Dest.y = dest.y; m_Dest.z = dest.z;}

	inline void SetDestination(vec3d dest) {m_Dest = (vec3f)dest;}

	const vec3f GetDestination(void) {return m_Dest;}

	inline void SetRadius(const float fRadius) { m_fRadius = fRadius; }
	inline void SetTarget(Object * targ) { m_pTarget = targ; }

	inline void Own(SGKAgent * me){m_Brain.getOwned(me);}

	Object * GetTehObject(){return m_pObject;}
	Object * GetTarget(){return m_pTarget;}
};

